package com.gopay.checkorder.service.impl.expay;

import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.NuccConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.bank.nucc.expay.NuccExpayBaseMessage;
import com.gopay.common.domain.bank.nucc.expay.query.res.NuccExpayQueryBodyRes;
import com.gopay.common.domain.bank.nucc.expay.query.res.NuccExpayQueryRes;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.remote.bank.ExPayInteractRemoteService;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * 网联快捷对账服务类
 * 
 * @ClassName: CheckOrderNuccExPayImpl
 * @author w_jiqing
 * @date 2017年7月18日 上午10:51:49
 */
public class CheckOrderNuccExPayImpl implements BankOrderService {

    private final static Logger logger = LoggerFactory.getLogger(CheckOrderNuccExPayImpl.class);

    @Resource(name = "bankExPayClient")
    private ExPayInteractRemoteService bankExPayClient;

    @Resource(name = "bankOrderManager")
    protected BankOrderManager bankOrderManager;

    @Override
    public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
        CheckOrderResult checkOrderResult = new CheckOrderResult();
        checkOrderResult.setSuccess(false);
        checkOrderResult.setOrderId(bankOrder.getOrderId());

        NuccExpayBaseMessage base = new NuccExpayBaseMessage();
        base.setOrderId(bankOrder.getOrderId());
        base.setBankOrderId(bankOrder.getOutOrderId());
        base.setBank(bankOrder.getBankCode());
        base.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
        base.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));

        Result result = new Result();
        try {

            // 如果是退款订单赋值原银行订单号
            if (BisBankBusinessProd._12.value.equals(bankOrder.getBankBizProdCode())) {
                base.setTkOriBankOrderId(bankOrder.getOriOutOrderId());
            }
            result = bankExPayClient.queryOrder(base);
            if (result == null || !result.isSuccess()) {
                logger.error("bankClient fail.");
                if (result == null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())) {
                    BankCountDownLatch.failIncrease(bankOrder.getBankCode());
                }
                logger.error(ToStringBuilder.reflectionToString(result, ToStringStyle.DEFAULT_STYLE));
                checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
                checkOrderResult.setErrMsg("系统返回对账结果为空");
                return checkOrderResult;
            }
            NuccExpayQueryRes res = (NuccExpayQueryRes) result.getDefaultModel();
            if (null == res) {
                checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
                checkOrderResult.setErrMsg("系统返回对账结果为空");
                return checkOrderResult;
            }
            NuccExpayQueryBodyRes resBody = res.getMsgBody();
            if (NuccConstants.NUCC_SYSRTNCD_SUCCESS.equals(resBody.getSysRtnInf().getSysRtnCd())) {
                // 系统返回码成功，才能获取到原交易状态
                String oriStatus = resBody.getBizInf().getOriTrxStatus();
                if(bankOrder.getTransBatchNo()==null&&resBody!=null&&resBody.getBizInf()!=null&&resBody.getBizInf().getOriBatchId()!=null){
                	bankOrder.setTransBatchNo(resBody.getBizInf().getOriBatchId());
                    bankOrderManager.update(bankOrder);
                }
                if (NuccConstants.NUCC_TRXSTATUSCD_SUCCESS.equals(oriStatus)
                        || NuccConstants.NUCC_EXCEPTION_SUCCESS.equals(oriStatus)) {
                    // 交易成功
                    checkOrderResult.setSuccess(true);
                    InAccInfo accInfo = new InAccInfo();
                    accInfo.setOrderId(bankOrder.getOrderId());
                    String  amount =resBody.getBizInf().getOriTrxAmt();
                    accInfo.setAmount(new BigDecimal(amount.substring(amount.indexOf("CNY")+3, amount.length())));
                    accInfo.setRetCode("00");
                    accInfo.setCardType(BankCardType.Unknown.toString());
                    checkOrderResult.setAccInfo(accInfo);
                    logger.error("网联快捷订单" + bankOrder.getOrderId() + "交易状态为:" + oriStatus + "，交易成功。");
                    // 交易成功，需获取银行返回的付款行银行流水号，退款时使用
                    bankOrder.setBankOrderId(resBody.getBizInf().getDbtrBankId());
                    bankOrderManager.update(bankOrder);
                } else if (NuccConstants.NUCC_TRXSTATUSCD_FAIL.equals(oriStatus)
                        || NuccConstants.NUCC_EXCEPTION_FAIL.equals(oriStatus)) {
                    // 交易失败
                    InAccInfo accInfo = new InAccInfo();
                    accInfo.setOrderId(bankOrder.getOrderId());
                    String  amount =resBody.getBizInf().getOriTrxAmt();
                    accInfo.setAmount(new BigDecimal(amount.substring(amount.indexOf("CNY")+3, amount.length())));
                    if (NuccConstants.NUCC_SYSRTNCD_SUCCESS.equals(resBody.getBizInf().getOriSysRtnCd())) {
                        accInfo.setRetCode(resBody.getBizInf().getOriBizStsCd());
                    } else {
                        accInfo.setRetCode(resBody.getBizInf().getOriSysRtnCd());
                    }

                    accInfo.setCardType(BankCardType.Unknown.toString());
                    checkOrderResult.setAccInfo(accInfo);
                    checkOrderResult.setBankFailure(true);
                    logger.error("网联快捷订单" + bankOrder.getOrderId() + "交易状态为:" + oriStatus + "，交易失败。");
                    checkOrderResult.setErrMsg("银行返回失败,原交易系统描述："+resBody.getBizInf().getOriSysRtnDesc()+"，原交易业务描述："+resBody.getBizInf().getOriBizStsDesc());
                } else if (NuccConstants.NUCC_TRXSTATUSCD_PROCESSING.equals(oriStatus)) {
                    // 处理中
                    logger.error("网联快捷订单" + bankOrder.getOrderId() + "交易状态为:" + oriStatus + "，交易进行中。");
                    checkOrderResult.setErrMsg("银行返回处理中");
                } else {
                    logger.error("网联快捷订单" + bankOrder.getOrderId() + "交易状态为:" + oriStatus + "，交易进行中。");
                    checkOrderResult.setErrMsg("原交易系统描述："+resBody.getBizInf().getOriSysRtnDesc()+"，原交易业务描述："+resBody.getBizInf().getOriBizStsDesc());
                }
            } else {
                // 系统返回码错误，交易处理中
                logger.error("网联快捷订单:" + bankOrder.getOrderId() + "系统返回码为:" + resBody.getSysRtnInf().getSysRtnCd()
                        + "，系统返回描述：" + resBody.getSysRtnInf().getSysRtnDesc());
                checkOrderResult.setErrMsg("查询交易系统描述："+resBody.getSysRtnInf().getSysRtnDesc()+"，查询交易系统返回码："+resBody.getSysRtnInf().getSysRtnCd()+")");
            }
        } catch (Exception e) {
            logger.error("bankClient fail.", e);
            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
            checkOrderResult.setErrMsg("对账调用bis失败");
            return checkOrderResult;
        }
        return checkOrderResult;
    }

    @Override
    public BankOrder getDbOrder() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BaseMessage dayend(String bank_bus) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result getDayendMsg(String string) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List<CheckOrderResult> checkDayend(String bank_bus) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
        // TODO Auto-generated method stub
        return null;
    }

}
